Player Summary

Row

Data Table

Row

Variable Classification

*If not specified, each stat is an average per game.

Name: Name of player.

Team: Team of player.

GP: Games played.

MPG: Minutes per game.

PPG: Points per game.

FGM: Field goals made.

FGA: Field goal attempts.

FGP: Field goal percentage.

TPM: Three point made.

TPA: Three point attempts.

TPP: Three point percentage.

FTM: Free throw made.

FTA: Free throw attempt.

FTP: Free throw percentage.

ORB: Offensive rebounds.

DRB: Defensive rebounds.

APG: Assists per game.

SPG: Steals per game.

BPG: Blocks per game.

TOV: Turnovers per game.

Salary: Salary for 2022-2023 season.

Advanced Statistics:

TPAR: Total points, assists, and rebounds.

PER: Player efficiency rating per game.

PERM: Player efficiency rating per minute.

eFGP: Effective field goal percentage.

TSP: True shooting percentage.

Team Summary

Row

Data Table

Betting Odds (Team)

Row

Data Table (Betting Summary)

Visual Data Analysis

Row

Scatter Plot (PPG vs. Salary)

Scatter Plot (RPG vs. Salary)

Scatter Plot (APG vs. Salary)

Scatter Plot (TPAR vs. Salary)

Scatter Plot (PER vs. Salary)

Scatter Plot (PERM vs. Salary)

---
title: "NBA Betting Dashboard"
output: 
  flexdashboard::flex_dashboard:
    theme:
      version: 4
      bootswatch: default
      navbar-bg: "#ADD8E6"
    orientation: columns
    vertical_layout: fill
    source_code: embed
---
<style>
.chart-title 
  {  
    /* chart_title  */
    font-size: 18px;
    font-family: Overpass;
  }
body
  {
      /* Normal  */
      font-size: 16px;
  }
</style>

```{css color tabs}
/* Set font color of inactive tab to green */
.nav-tabs-custom .nav-tabs > li > a 
  {
    color: blue;
  } 

/* Set font color of active tab to red */
.nav-tabs-custom .nav-tabs > li.active > a 
  {
    color: purple;
  } 

/* To set color on hover */
.nav-tabs-custom .nav-tabs > li.active > a:hover 
  {
    color: black;
  }

<style type="text/css"> .sidebar 
  { 
    overflow: auto; 
  } 
</style>
```

```{r setup, include=FALSE}
library(flexdashboard)
```

```{r packages}
pacman::p_load(rvest, tidyverse, ggplot2, stringr, esquisse, plotly)
```

```{r scraping & cleaning (salary)}
link1 = "https://hoopshype.com/salaries/players/"
page1 = read_html(link1)

name = page1 %>%
  html_nodes("tbody .name") %>% html_text()
salary = page1 %>%
  html_nodes("tbody .hh-salaries-sorted") %>% html_text()

name <- gsub("\t", "", name)
name <- gsub("\n", "", name)

salary <- gsub("\n", "", salary)
salary <- gsub("\t", "", salary)
salary <- gsub("\\$", "", salary)
salary <- gsub(",", "", salary)

nba_salary <- data.frame(name, salary)

nba_salary$salary <- as.numeric(nba_salary$salary)
```

```{r scraping & cleaning (stats)}
nba_stats = data.frame()

for (pages in c(1,2,3,4)) 
  {
    link2 = paste0("https://basketball.realgm.com/nba/stats/2023/Averages/Qualified/minutes/All/desc/", pages, "/Regular_Season")  
    page2 = read_html(link2)
    
name = page2 %>% 
  html_nodes(".nowrap") %>% html_text()
    
team = page2 %>% 
  html_nodes(".nowrap+ td") %>% html_text()

mpg = page2 %>% 
  html_nodes("td:nth-child(3)") %>% html_text()

gp = page2 %>% 
  html_nodes("td:nth-child(4)") %>% html_text()

mpg = page2 %>% 
  html_nodes("td:nth-child(5)") %>% html_text()

ppg = page2 %>% 
  html_nodes("td:nth-child(6)") %>% html_text()

fgm = page2 %>% 
  html_nodes("td:nth-child(7)") %>% html_text()

fga = page2 %>% 
  html_nodes("td:nth-child(8)") %>% html_text()

fgp = page2 %>% 
  html_nodes("td:nth-child(9)") %>% html_text()

tpm = page2 %>% 
  html_nodes("td:nth-child(10)") %>% html_text()

tpa = page2 %>% 
  html_nodes("td:nth-child(11)") %>% html_text()

tpp = page2 %>% 
  html_nodes("td:nth-child(12)") %>% html_text()

ftm = page2 %>% 
  html_nodes("td:nth-child(13)") %>% html_text()

fta = page2 %>% 
  html_nodes("td:nth-child(14)") %>% html_text()

ftp = page2 %>% 
  html_nodes("td:nth-child(15)") %>% html_text()

orb = page2 %>%
  html_nodes("td:nth-child(16)") %>% html_text()

drb = page2 %>%
  html_nodes("td:nth-child(17)") %>% html_text()

rpg = page2 %>%
  html_nodes("td:nth-child(18)") %>% html_text()

apg = page2 %>%
  html_nodes("td:nth-child(19)") %>% html_text()

spg = page2 %>%
  html_nodes("td:nth-child(20)") %>% html_text()

bpg = page2 %>%
  html_nodes("td:nth-child(21)") %>% html_text()

tov = page2 %>%
  html_nodes("td:nth-child(22)") %>% html_text()

pf = page2 %>%
  html_nodes("td:nth-child(23)") %>% html_text()

nba_stats <- rbind(nba_stats, as.data.frame(cbind(name, team, gp, mpg, ppg, fgm, fga, fgp, tpm, tpa, tpp, ftm, fta, ftp, orb, drb, rpg, apg, spg, bpg, tov, pf)))
  }

nba_stats <- nba_stats %>% mutate_at(c("ppg", "fgm", "fga", 
                                       "fgp", "tpm", "tpa", 
                                       "tpp", "ftm", "fta", 
                                       "ftp", "orb", "drb", 
                                       "rpg", "apg", "spg", 
                                       "bpg", "tov", "pf", "mpg"), as.numeric)
```

```{r merge data}
nba <- left_join(nba_stats, nba_salary, by = "name")

nba$team <- as.factor(nba$team)

nba <- na.omit(nba)

tpar <- rep(NA, nrow(nba))

for (i in 1:nrow(nba)) 
  {
    tpar[i] = nba$ppg[i] + nba$apg[i] + nba$rpg[i]
  }

nba <- as.data.frame(cbind(nba, tpar))

per <- rep(NA, nrow(nba))

for (i in 1:nrow(nba)) 
  {
    per[i] = (nba$ppg[i] + nba$apg[i] + nba$rpg[i] + nba$spg[i] + nba$bpg[i] - 
                nba$tov[i] - ((nba$fga[i] + nba$tpa[i] + nba$fta[i]) - (nba$fgm[i] + nba$tpm[i] + nba$ftm[i])))
  }

nba <- as.data.frame(cbind(nba, per))

perm <- rep(NA, nrow(nba))

for (i in 1:nrow(nba))
  {
    perm[i] = nba$per[i]/nba$mpg[i]
  }

nba <- as.data.frame(cbind(nba, perm))

nba$perm <- round(nba$perm, digits = 2)

eFGP <- rep(NA, nrow(nba))

for (i in 1:nrow(nba)) 
  {
    eFGP[i] <- ((nba$fgm[i] + (1/2)*nba$tpm[i])/nba$fga[i])*100
  }

eFGP <- round(eFGP, digits = 2)

nba <- as.data.frame(cbind(nba, eFGP))

TSP <- rep(NA, nrow(nba))

for (i in 1:nrow(nba)) 
  {
    TSP[i] <- (nba$ppg[i]/(2*(nba$fga[i] + 0.44*nba$fta[i])))*100
  }

TSP <- round(TSP, digits = 2)

nba <- as.data.frame(cbind(nba, TSP))
```

Player Summary
===

Row {data-width=650}
-----------------------------------------------------------------------

### Data Table

```{r data table 1}
DT::datatable(nba, rownames = FALSE, 
              options = list(columnDefs = list(list(className = 'dt-center', targets = 1:22))))
```

Row {data-width=650}
-----------------------------------------------------------------------

### Variable Classification

*If not specified, each stat is an average per game.

Name: Name of player.

Team: Team of player.

GP: Games played.

MPG: Minutes per game.

PPG: Points per game.

FGM: Field goals made.

FGA: Field goal attempts.

FGP: Field goal percentage.

TPM: Three point made.

TPA: Three point attempts.

TPP: Three point percentage.

FTM: Free throw made.

FTA: Free throw attempt.

FTP: Free throw percentage.

ORB: Offensive rebounds.

DRB: Defensive rebounds.

APG: Assists per game.

SPG: Steals per game.

BPG: Blocks per game.

TOV: Turnovers per game.

Salary: Salary for 2022-2023 season.

Advanced Statistics:

TPAR: Total points, assists, and rebounds.

PER: Player efficiency rating per game.

PERM: Player efficiency rating per minute.

eFGP: Effective field goal percentage.

TSP: True shooting percentage.

Team Summary
===

Row {data-width=650}
-----------------------------------------------------------------------

### Data Table

```{r data table 2}
nba_team <- rep(NA, 30)

nba_team <- nba %>% group_by(team) %>%
  summarise(avgPoints = round(mean(ppg), digits = 2), avgRebounds = round(mean(rpg), digits = 2),
            avgAssists = round(mean(apg), digits = 2), avgPER = round(mean(per), digits = 2),
            avgTPAR = round(mean(tpar), digits = 2),
            avgEFG = round(mean(eFGP), digits = 2), avgTSP = round(mean(TSP), digits = 2))

DT::datatable(nba_team, rownames = FALSE, 
              options = list(columnDefs = list(list(className = 'dt-center', targets = 1:6))))
```

Betting Odds (Team)
===

Row {data-width=650}
-----------------------------------------------------------------------

### Data Table (Betting Summary)

```{r scraping & cleaning}
link3 = "https://www.covers.com/sport/basketball/nba/statistics/team-betting/2022-2023"
page3 = read_html(link3)

teamName = page3 %>%
  html_nodes("td:nth-child(2)") %>% html_text()

againstSpread = page3 %>%
  html_nodes("td:nth-child(3)") %>% html_text()

againstSpreadP = page3 %>%
  html_nodes("td:nth-child(4)") %>% html_text()

W_L = page3 %>%
  html_nodes("td:nth-child(5)") %>% html_text()

overUnder = page3 %>%
  html_nodes("td:nth-child(6)") %>% html_text()

pointsPerGame = page3 %>%
  html_nodes("td:nth-child(7)") %>% html_text()

pointsAgainst = page3 %>%
  html_nodes("td:nth-child(8)") %>% html_text()

pointMarginPerGame = page3 %>%
  html_nodes("td:nth-child(9)") %>% html_text()

teamName <- gsub(" ", "", teamName)
teamName <- gsub("\r", "", teamName)
teamName <- gsub("\n", "", teamName)

nba_bet <- as.data.frame(cbind(teamName, againstSpread, againstSpreadP, W_L, overUnder, pointsPerGame, pointsAgainst, pointMarginPerGame))
```

```{r data table 3}
DT::datatable(nba_bet, rownames = FALSE, 
              options = list(columnDefs = list(list(className = 'dt-center', targets = 1:7))))
```

Visual Data Analysis
===

Row {.tabset data-width=650}
-----------------------------------------------------------------------

### Scatter Plot (PPG vs. Salary)

```{r EDA 3}
plot1 <- ggplot(nba, aes(x = salary, y = ppg,  
                text = paste0("Player: ", name, "\n", "PPG: ", ppg, "\n", "Salary: ", salary))) +
  geom_point(shape = "", colour = "#45b6fe") + labs(x = "Salary", y = "PPG", title = "NBA Points Per Game vs. Salary", subtitle = "2022-2023 Season") +
  theme_classic()

font1 <- list(family = "Mono", size = 15, color = "black")
label1 <- list(bgcolor = "lightblue", font = font1)

ggplotly(plot1, tooltip = "text") %>%
  style(hoverlabel = label1) %>%
  layout(font = font1)
```

### Scatter Plot (RPG vs. Salary)

```{r EDA 4}
plot2 <- ggplot(nba, aes(x = salary, y = rpg,  
                text = paste0("Player: ", name, "\n", "RPG: ", rpg, "\n", "Salary: ", salary))) +
  geom_point(shape = "bullet", colour = "#296d98") + labs(x = "Salary", y = "RPG", title = "NBA Rebounds Per Game vs. Salary", subtitle = "2022-2023 Season") +
  theme_classic()

font2 <- list(family = "Mono", size = 15, color = "black")
label2 <- list(bgcolor = "lightblue", font = font2)

ggplotly(plot2, tooltip = "text") %>%
  style(hoverlabel = label2) %>%
  layout(font = font2)
```

### Scatter Plot (APG vs. Salary)

```{r EDA 5}
plot3 <- ggplot(nba, aes(x = salary, y = apg,  
                text = paste0("Player: ", name, "\n", "APG: ", apg, "\n", "Salary: ", salary))) +
  geom_point(shape = "bullet", colour = "#0e2433") +
  labs(x = "Salary", y = "PPG", title = "NBA Assists Per Game vs. Salary", subtitle = "2022-2023 Season") +
  theme_classic()

font3 <- list(family = "Mono", size = 15, color = "black")
label3 <- list(bgcolor = "lightblue", font = font3)

ggplotly(plot3, tooltip = "text") %>%
  style(hoverlabel = label3) %>%
  layout(font = font3)
```

### Scatter Plot (TPAR vs. Salary)

```{r EDA 6}
plot4 <- ggplot(nba, aes(x = salary, y = tpar,  
                text = paste0("Player: ", name, "\n", "TPAR: ", tpar, "\n", "Salary: ", salary))) +
  geom_point(shape = "bullet", colour = "#0e2433") +
  labs(x = "Salary", y = "PPG", title = "NBA Total Points + Rebounds + Assists Per Game vs. Salary", subtitle = "2022-2023 Season") +
  theme_classic()

font4 <- list(family = "Mono", size = 15, color = "black")
label4 <- list(bgcolor = "lightblue", font = font4)

ggplotly(plot4, tooltip = "text") %>%
  style(hoverlabel = label4) %>%
  layout(font = font4)
```

### Scatter Plot (PER vs. Salary)

```{r EDA 7}
plot5 <- ggplot(nba, aes(x = salary, y = per,  
                text = paste0("Player: ", name, "\n", "PER: ", per, "\n", "Salary: ", salary))) +
  geom_point(shape = "bullet", colour = "#0e7733") +
  labs(x = "Salary", y = "PER", title = "NBA Player Efficiency Rating (PER) vs. Salary", subtitle = "2022-2023 Season") +
  theme_classic()

font5 <- list(family = "Mono", size = 15, color = "black")
label5 <- list(bgcolor = "lightblue", font = font5)

ggplotly(plot5, tooltip = "text") %>%
  style(hoverlabel = label5) %>%
  layout(font = font5)
```

### Scatter Plot (PERM vs. Salary)

```{r EDA 8}
plot6 <- ggplot(nba, aes(x = salary, y = perm,  
                text = paste0("Player: ", name, "\n", "PERM: ", round(perm, digits = 2), "\n", "Salary: ", salary))) +
  geom_point(shape = "bullet", colour = "maroon") +
  labs(x = "Salary", y = "PER", title = "NBA Player Efficiency Rating per Minute (PERM) vs. Salary", subtitle = "2022-2023 Season") +
  theme_classic()

font6 <- list(family = "Mono", size = 15, color = "black")
label6 <- list(bgcolor = "lightblue", font = font6)

ggplotly(plot6, tooltip = "text") %>%
  style(hoverlabel = label6) %>%
  layout(font = font6)
```